﻿
#region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;

#endregion

namespace MarketPulse.BusinessLogic.Private.StateMachine
{
    internal interface IVisitState
    {

        /// <summary>
        /// Method used to assign the Visit to a specific user based on the user guid value supplied
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        /// <param name="userGuid">The Guid of the user to assign this Visit to</param>
        /// <param name="plannedDateTime">The date the Visit is planned to take place</param>
        bool Assign(IVisitStateContext context, bool tryTransition, Guid userGuid, DateTime plannedDateTime);

        /// <summary>
        /// Method used to unassign the Visit
        /// </summary> 
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        /// <param name="payment">Enumeration vairable used to deterine whether payment should be honoured</param>               
        bool Unassign(IVisitStateContext context, bool tryTransition, Visit.PaymentStatus payment);

        /// <summary>
        /// Method used to release the Visit and make it ready to be assigned
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool Release(IVisitStateContext context, bool tryTransition);
 
        /// <summary>
        /// Method used to save the information for this Visit captured as part of the data entry process
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool StartDataEntry(IVisitStateContext context, bool tryTransition);

        /// <summary>
        /// Method used to save the information for this Visit captured as part of the data entry process
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        /// <param name="responses">The XML response set to attach to the survey instance for the Visit</param>
        bool DataEnter(IVisitStateContext context, bool tryTransition, XElement responses);

        /// <summary>
        /// Method used to complete the data entry process for this Visit
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool CompleteDataEntry(IVisitStateContext context, bool tryTransition);

        #region QA Methods

        /// <summary>
        /// Method used to begin the QA process for this Visit
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool QAStartDataEntry(IVisitStateContext context, bool tryTransition);

        /// <summary>
        /// Method used to enter data during the QA process for this Visit
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool QADataEnter(IVisitStateContext context, bool tryTransition);

        /// <summary>
        /// Method used to approve the QA of the responses gathered as part of this Visit
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool QAApprove(IVisitStateContext context, bool tryTransition);

        /// <summary>
        /// Method used to fail the QA of the responses gathered as part of this Visit
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool QAFail(IVisitStateContext context, bool tryTransition);

        /// <summary>
        /// Method used to put the QA process on hold whilst other aspects of the Visit are adressed 
        /// (i.e. query from the branch, clarification of an answer by the shopper etc...)
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool QAPutOnHold(IVisitStateContext context, bool tryTransition);

        /// <summary>
        /// Method used to reopen the QA process for this Visit
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool QAReopen(IVisitStateContext context, bool tryTransition);

        /// <summary>
        /// Method used to mark this Visit as Ready to Transfer
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool MarkReadyForTransfer(IVisitStateContext context, bool tryTransition);

        /// <summary>
        /// Method used to create a new version of this visit for revisiting
        /// </summary>
        /// <param name="context">The current state machine context</param>
        /// <param name="tryTransition">Whether to simulate or actually perform a transition</param>
        bool Revisit(IVisitStateContext context, bool tryTransition);

        #endregion

        /// <summary>Property to allow read-only access to the database defined Guid for the current visit state</summary>
        Guid StateGuid { get; }

        /// <summary>
        /// Property to set and get a flag to indicate if an exception should be thrown when
        /// an invalid transition is attempted.
        /// </summary>
        bool ThrowIfInvalid { get; set; }

    }
}
